package com.fs.activiti5.controller;

import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import lombok.extern.log4j.Log4j;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.CommentEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fs.activiti5.service.ActivitiService;
import com.fs.activiti5.vo.Affair;
import com.fs.activiti5.vo.CommentVo;
import com.fs.activiti5.vo.DeploymentVo;
import com.fs.activiti5.vo.ProcessDefinitionVo;
import com.fs.activiti5.vo.TaskVo;
import com.fs.base.param.SysConstant;
import com.fs.base.pojo.Attachment;
import com.fs.base.repository.AttachmentRepository;
import com.fs.base.service.BaseService;
import com.fs.base.utils.ApplicationUtils;
import com.fs.base.utils.PageHeper;
import com.fs.base.vo.DataGrid;
import com.fs.base.vo.JsonResponse;
import com.fs.base.vo.SysPath;
import com.fs.flow.pojo.FlowCondition;
import com.fs.flow.pojo.ProcessTaskConfig;
import com.fs.flow.repository.FlowConditionRepository;
import com.fs.flow.repository.ProcessTaskConfigRepository;
import com.fs.jzzn.param.QueryMap;
import com.fs.jzzn.pojo.Information;
import com.fs.jzzn.pojo.NoteDebit;
import com.fs.jzzn.pojo.Project;
import com.fs.jzzn.pojo.TaskCandidateUsers;
import com.fs.jzzn.repository.InformationRepository;
import com.fs.jzzn.repository.ProjectRepository;


@Controller
@RequestMapping("/console/activiti")
@Log4j
public class ActivitiController {
	@Autowired  private ActivitiService activitiService;
	@Autowired private AttachmentRepository attachmentRepository;
	@Autowired private ProjectRepository projectRepository;
	@Autowired private InformationRepository informationRepository;
	@Autowired private ProcessTaskConfigRepository processTaskConfigRepository;
	@Autowired private FlowConditionRepository flowConditionRepository;
	@Autowired private BaseService baseService;
	
	/**
	 * 流程发布首页
	 * @param req
	 * @return
	 */
	@GetMapping("deploy/index")
	public String index(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/deploy/index");
	}
	
	/**
	 * 流程定义首页
	 * @param req
	 * @return
	 */
	@GetMapping("deploy/definition")
	public String definition(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/deploy/definition");
	}
	
	/**
	 * 最新流程定义列表
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("deploy/definitionList")
	public DataGrid definitionList(HttpServletRequest request,String name){
		List<ProcessDefinition> list =  activitiService.findProcessDefinitionMaxVersion(name);
		return DataGrid.gridBuilder(ProcessDefinitionVo.list(list));
	}
	
	/**
	 * 流程部署列表
	 * @return
	 */
	@ResponseBody
	@RequestMapping("deploy/list")
	public DataGrid deployList(HttpServletRequest request){
		List<Deployment> list =  activitiService.findDeployList();
		return DataGrid.gridBuilder(DeploymentVo.list(list));
	}
	
	/**
	 * 流程部署图定义列表
	 * @param deploymentId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("processDefinition/list")
	public DataGrid processDefinitionList(String deploymentId){
		List<ProcessDefinition> list =  activitiService.findProcessDefinitionList(deploymentId);
		return DataGrid.gridBuilder(ProcessDefinitionVo.list(list));
	}
	
	/**
	 * 查看流程图定义
	 * @param deploymentId
	 * @param imageName
	 * @param out
	 * @return
	 */
	@RequestMapping("processDefinition/imageView")
	public String processDefinitionImageView(String deploymentId,String imageName,PrintWriter out){
		InputStream in = activitiService.getProcessDefImage(deploymentId,imageName);
		try {
			for(int b=-1;(b=in.read())!=-1;){
				out.write(b);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			out.close();
		}
		return null;
	}
	
	
	/**
	 * 流程图发布页面
	 * @param req
	 * @return
	 */
	@GetMapping("deploy")
	public String deployA(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/deploy/deployZip");
	}
	
	
	/**
	 * 流程提交发布
	 * @param id
	 * @param flowName
	 * @return
	 */
	@ResponseBody
	@RequestMapping("deploy")
	public JsonResponse deployB(String deployId,String flowName){
		try {
			Boolean deploySuccess = false;
			File zipFile = null;
			if(StringUtils.isNotBlank(deployId)){
				// 删除数据库记录并删除文件
				Attachment att = attachmentRepository.findOne(deployId);
				String path = att.getUrl();
				zipFile = new File(path);
				deploySuccess = activitiService.deploy(flowName,zipFile);
				//attachmentRepository.delete(att);
				if(zipFile!=null) {
					zipFile.deleteOnExit();
				}
			}
			if(deploySuccess){
				return JsonResponse.success();
			}else{
				return JsonResponse.error("发布失败！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 流程部署删除
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("deploy/delete")
	public JsonResponse delete(String id){
		try {
			if(StringUtils.isNotBlank(id)){
				activitiService.deleteDeploymentById(id);
			}
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	/**
	 * 待办首页
	 * @param req
	 * @return
	 */
	@GetMapping("task/todo")
	public String taskTodo(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/task/todo");
	}
	
	/**
	 * 待办列表
	 * @param req
	 * @param taskName
	 * @return
	 */
	@ResponseBody
	@RequestMapping("task/todoList")
	public DataGrid todoList(HttpServletRequest req,String taskName){
		PageRequest page = PageHeper.pageRequest(req);
		List<TaskVo> list = activitiService.getTodoList(ApplicationUtils.User().getNickName(),taskName,page );
		/*for(TaskVo vo :list){
			String processInstanceId = vo.getProcessInstanceId();
	    	HistoricProcessInstance hp = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
	    	if(hp!=null){
	    		vo.setBusinessKey(hp.getBusinessKey());
	    		vo.setFlowName(hp.getName());
	    	}
		}*/
		/*TaskService taskService = activitiService.getTaskService();
		String sql = "SELECT t.ID_, t.PROC_INST_ID_,t.NAME_,t.ASSIGNEE_,t.CREATE_TIME_,p.NAME_ as processName,p.BUSINESS_KEY_ FROM act_ru_task t LEFT JOIN act_hi_procinst p ON p.PROC_INST_ID_ = t.PROC_INST_ID_  WHERE t.ASSIGNEE_ = #{nickname} ";
		List<Task> list = taskService.createNativeTaskQuery().sql(sql).parameter("nickname", ApplicationUtils.User().getNickName()).*/
		return DataGrid.gridBuilder(list);
	}
	
	
	/**
	 * 已办
	 */
	@GetMapping("task/hasdo")
	public String taskHasdo(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/task/hasdo");
	}
	
	/**
	 * 已办列表
	 * @param req
	 * @param taskName
	 * @return
	 */
	@ResponseBody
	@RequestMapping("task/hasdoList")
	public DataGrid hasdoList(HttpServletRequest req,String taskName){
		PageRequest page = PageHeper.pageRequest(req);
		List<TaskVo> list = activitiService.getHasdoList(ApplicationUtils.User().getNickName(),taskName,page );
		return DataGrid.gridBuilder(list);
	}
	
	
	
	
	/**
	 * 启动工程流程
	 * @param request
	 * @param projectId
	 * @return
	 */
	@Transactional
	@ResponseBody
	@GetMapping("startProjectProcess")
	public JsonResponse startProjectProcess(HttpServletRequest request,String projectId){
		try {
			boolean isSuccess = false;
			if(StringUtils.isNotBlank(projectId)){
				Project project = projectRepository.findOne(projectId);
				String orgNo = project.getOrgNo();
				if(StringUtils.isBlank(orgNo) || !QueryMap.projectCandidateUserMap.containsKey(orgNo)){
					return JsonResponse.error("此单项工程所属组织机构流程还没有上线，请耐心等待！");
				}
				isSuccess = activitiService.startProjectProcess(project);
			}
			if(isSuccess){
				return JsonResponse.success();
			}else{
				return JsonResponse.error("启动流程失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	/**
	 * 查看当前流程图
	 * @param req
	 * @return
	 */
	@GetMapping("viewImage")
	public String viewImage(String taskId,HttpServletRequest request) {
		Task task= activitiService.getTaskService().createTaskQuery() // 创建任务查询
				.taskId(taskId) // 根据任务id查询
				.singleResult();
		if(task!=null){
			Set<String> assignee = new HashSet<>();
			List<IdentityLink> links = activitiService.getTaskService().getIdentityLinksForTask(taskId);
			for (IdentityLink link : links){
				assignee.add(link.getUserId());
			}
			request.setAttribute("assignee",assignee);
			
			String processDefinitionId=task.getProcessDefinitionId(); // 获取流程定义id
			//System.out.println("processDefinitionId: "+ processDefinitionId);
			ProcessDefinition processDefinition=activitiService.getRepositoryService().createProcessDefinitionQuery() // 创建流程定义查询
					.processDefinitionId(processDefinitionId) // 根据流程定义id查询
					.singleResult();
			request.setAttribute("deploymentId",processDefinition.getDeploymentId()); // 部署id
			request.setAttribute("imageName", processDefinition.getDiagramResourceName()); // 图片资源文件名称
			
			// 查看当前活动坐标
			ProcessDefinitionEntity processDefinitionEntity =(ProcessDefinitionEntity) activitiService.getRepositoryService().getProcessDefinition(processDefinitionId);
			String processInstanceId = task.getProcessInstanceId(); // 获取流程实例id
			//System.out.println("processInstanceId:"+ processInstanceId);
			// 根据流程实例id查询活动实例
			ProcessInstance pi =activitiService.getRuntimeService().createProcessInstanceQuery()
					.processInstanceId(processInstanceId) 
					.singleResult();
			ActivityImpl activityImpl = processDefinitionEntity.findActivity(pi.getActivityId()); // 根据活动id查询活动实例
			//System.out.println(activityImpl);
			request.setAttribute("x", activityImpl.getX());
			request.setAttribute("y", activityImpl.getY());
			request.setAttribute("width", activityImpl.getWidth());
			request.setAttribute("height", activityImpl.getHeight());
		}else{
			request.setAttribute("msg", "当前流程执行完结！");
		}
		
		return SysPath.BACK_PATH.concat("/activiti/viewImage");
	}
	
	/**
	 * 通过流程实例id查看流程图
	 * @param instId
	 * @param request
	 * @return
	 */
	@GetMapping("viewImageByInstId")
	public String viewImageByInstId(String instId,HttpServletRequest request) {
		Task task= activitiService.getTaskService().createTaskQuery() // 创建任务查询
				.processInstanceId(instId) // 根据任务id查询
				.singleResult();
		if(task==null){
			/*HistoricProcessInstance processInstance =  activitiService.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(instId).singleResult();  
	        //获取流程图  
	        BpmnModel bpmnModel = activitiService.getRepositoryService().getBpmnModel(processInstance.getProcessDefinitionId());  
			request.setAttribute("", bpmnModel.getd);
			return SysPath.BACK_PATH.concat("/activiti/viewImage");*/
			request.setAttribute("msg", "当前流程已经执行完结！");
			return SysPath.BACK_PATH.concat("/activiti/viewNoImage");
		}
		return viewImage(task.getId(),request);
	}
	
	
	/**
	 * 流程表单页面重定向
	 * @param taskId
	 * @param request
	 * @return
	 */
	@GetMapping("viewTaskForm")
	public String viewTaskForm(String taskId,HttpServletRequest request){
		String url = activitiService.findTaskFormKeyByTaskId(taskId);
		if(url.indexOf("?")>-1){
			url = url.concat("&taskId=").concat(taskId);
		}else{
			url = url.concat("?taskId=").concat(taskId);
		}
		return "redirect:".concat(url);
	}
	
	/**
	 * 项目流程执行表单
	 * @param req
	 * @return
	 */
	@GetMapping("projectProcessForm")
	public String projectProcessForm(String taskId,HttpServletRequest request) {
		Task task = activitiService.findTaskById(taskId);
		/*
		 * 业务数据回显
		 */
		Project p = activitiService.findBusinessObjectByTaskId(taskId);
		
		String url = "/project/projectProcessForm2";
		if("新建".equals(task.getName()) || "审计".equals(task.getName())){
			url = "/project/projectProcessForm";
			request.setAttribute("jsonVo",JSON.toJSON(p));
		}else{
			Information information = informationRepository.findOneBypNo(p.getPNo());
			if(information==null){ information = new Information(); }
			/*
			 * 设置项目部
			 */
			information.setDepartment(p.getDepartment());
			information.setOrgNo(p.getOrgNo());
			
			request.setAttribute("jsonVo",JSON.toJSON(information));
			request.setAttribute("pNo",p.getPNo());
		}
		request.setAttribute("taskId",taskId);
		/*
		 *当前流程节点处理线路
		 */
		Set<String> outComeList = activitiService.findTaskLinesByTaskId(taskId);
		request.setAttribute("outComeList",JSON.toJSON(outComeList));
		request.setAttribute("taskName",task.getName());
		
		//return "redirect:".concat(SysPath.BACK_PATH.concat("/activiti/task/todo?success=true"));
		return SysPath.BACK_PATH.concat(url);
	}
	
	/**
	 * 任务处理
	 * @param taskId
	 * @param request
	 * @return
	 */
	@Transactional
	@RequestMapping("submitTask")
	public String submitTask(String taskId, HttpServletRequest request) {
		Task task = activitiService.findTaskById(taskId);
		String outcome =  request.getParameter("outcome"); 
		String comment = request.getParameter("comment");
		String processInstanceId = task.getProcessInstanceId();
		Project project = activitiService.findBusinessObjectByTaskId(taskId);
		String taskName = task.getName();
		/*
		 * 添加批注
		 */
		if(StringUtils.isNotBlank(comment)){
			Authentication.setAuthenticatedUserId(ApplicationUtils.User().getNickName());
			comment =  "["+ taskName +"]"+ comment;
			
			activitiService.getTaskService().addComment(taskId, processInstanceId, comment);
		}
		
		Map<String, Object> variables = new HashMap<String, Object>();
		if(StringUtils.isNotBlank(outcome) && !"默认提交".equals(outcome)){
			variables.put("outcome", outcome);
		}
		
		/*String taskName = task.getName();
		if("新建".equals(task.getName())){
			if(project.getPNo().startsWith("WC")){
				variables.put("inforUser", "沈明安");
			}
			if(project.getPNo().startsWith("HS")){
				variables.put("inforUser", "张发锐");
			}
		}*/
		activitiService.getTaskService().complete(taskId, variables);
		if(!"驳回".equals(outcome)){ 
				Map<String, Object> map = ApplicationUtils.getRequestDatas();
				if("新建".equals(taskName) || "审计".equals(taskName)){
					project = copyMapData2Project(map);
					
					if( "审计".equals(taskName)){
						project.setStatus("完结");
						projectRepository.save(project);
					}
					
				}else {
					Information information = copyMapData2Information(map);
					information.setOrgNo(project.getOrgNo()); //设置组织结构
					information.setDepartment(project.getDepartment());
					informationRepository.save(information);
				}
			/**
			 * 更新状态
			 */
			/*if("新建".equals(taskName)){
				taskName = "	施工";
			}else if("施工".equals(taskName)){
				taskName = "	完工验收";
			}else if("完工验收".equals(taskName)){
				taskName = "	资管交维";
			}else if("资管交维".equals(taskName)){
				taskName = "	竣工资料";
			}else if("竣工资料".equals(taskName)){
				taskName = "	送审";
			}else if("送审".equals(taskName)){
				taskName = "	审计";
			}else if("审计".equals(taskName)){
				taskName = "完结";
			}
			taskName = taskName.trim();
			project.setStatus(taskName);
			projectRepository.save(project);*/
		}
		//处理完成后重定向到待办首页
		return "redirect:".concat(SysPath.BACK_PATH.concat("/activiti/task/todo?success=true"));
	}
	
	@SuppressWarnings("unchecked")
	private Project copyMapData2Project(Map<String, Object> data){
		Project obj = null;
		if(data.containsKey("id") && "".equals(data.get("id"))){
			obj = projectRepository.findOne(data.get("id").toString());
			/*
			 * 就数据格式化
			 */
			String json = JSON.toJSONString(obj);
			Map<String, Object> dataMap = JSON.parseObject(json, Map.class);
			/*
			 * 新数据覆盖
			 */
			dataMap.putAll(data);
			
			String _json = JSON.toJSONString(dataMap) ;
			obj = JSON.parseObject(_json, Project.class);
		}else{
			String _json = JSON.toJSONString(data) ;
			obj = JSON.parseObject(_json, Project.class);
		}
		return obj;
	}
	
	/**
	 * 批注列表
	 * @param req
	 * @param taskId
	 * @return
	 */
	@RequestMapping("task/commentList")
	@ResponseBody
	public DataGrid commentList(HttpServletRequest req,String taskId){
		List<CommentVo> rows = new ArrayList<>();
		List<Comment> list = activitiService.findCommentByTaskId(taskId);
		for(Comment c: list){
			CommentEntity cEntity = (CommentEntity) c;
			rows.add(new CommentVo(c.getTime(), c.getUserId(), cEntity.getMessage()));
		}
		return DataGrid.gridBuilder(rows);
	}
	
	@RequestMapping("process/hisProcessInstanceList")
	@ResponseBody
	public DataGrid hisProcessInstanceList(HttpServletRequest req,String taskId){
		List<HistoricProcessInstance> rows = activitiService.getHistoryService()
				.createHistoricProcessInstanceQuery() // 创建历史流程实例查询
		        .list();
		/*for(Comment c: list){
			rows.add(new CommentVo(c.getTime(), c.getUserId(), c.getFullMessage()));
		}*/
		return DataGrid.gridBuilder(rows);
	}
	
	/**
	 * 根据业务id查询审批信息
	 * @param projectId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("process/hisCommentList")
	public DataGrid hisCommentList(String processInstanceBusinessKey){
		List<CommentVo> rows = new ArrayList<>();
		if(StringUtils.isNotBlank(processInstanceBusinessKey)){
			//projectId = Project.class.getSimpleName() +"." + projectId;
			List<Comment> list = activitiService.findCommentByBussnessId(processInstanceBusinessKey);
			for(Comment c: list){
				rows.add(new CommentVo(c.getTime(), c.getUserId(), c.getFullMessage()));
			}
		}
		return DataGrid.gridBuilder(rows);
	}
	
	
	@SuppressWarnings("unchecked")
	private Information copyMapData2Information(Map<String, Object> data){
		Information obj = null;
		if(data.containsKey("id") && !"".equals(data.get("id"))){
			obj = informationRepository.findOne(data.get("id").toString());
			String json = JSON.toJSONString(obj);
			Map<String, Object> dataMap = JSON.parseObject(json, Map.class);
			dataMap.putAll(data);
			
			String _json = JSON.toJSONString(dataMap) ;
			obj = JSON.parseObject(_json, Information.class);
		}else{
			String _json = JSON.toJSONString(data) ;
			obj = JSON.parseObject(_json, Information.class);
		}
		return obj;
	}
	
	
	@GetMapping("deploy/processInstance")
	public String processInstance(HttpServletRequest req) {
		return SysPath.BACK_PATH.concat("/activiti/deploy/processInstance");
	}

	/**
	 * 最新流程定义列表
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping("deploy/processInstanceList")
	public DataGrid processInstanceList(HttpServletRequest request,String name){
		String userName = ApplicationUtils.User().getNickName();
		PageRequest pageable = PageHeper.pageRequest(request);
		Map<Object, Object> params = new HashMap<>();
		String orgNo = ApplicationUtils.User().getOrgNo();
		String sql = "SELECT p.END_ACT_ID_ as end_act_Id,   '"+ orgNo +"' as org_no, p.PROC_INST_ID_ as id,p.BUSINESS_KEY_ as business_key,p.END_TIME_ as end_time, p.PROC_DEF_ID_ as def_id,p.START_TIME_ as create_time,p.START_USER_ID_ as creater_id,p.NAME_ as affair_title,(select NAME_ from act_hi_taskinst t where t.EXECUTION_ID_ =p.ID_ order by START_TIME_ desc limit 1 ) as status  FROM act_hi_procinst p WHERE  1=1 ";
		String all = request.getParameter("all");
		if(StringUtils.isBlank(all)){
			sql += (" and p.START_USER_ID_ = :userName ");
			params.put("userName", userName);
		}
		//and 1=1
		if(StringUtils.isNotBlank(name)){
			params.put("affairTitle", name);
			sql += (" and  p.NAME_ like CONCAT('%',:affairTitle,'%') ");
		}
		
		Page<Affair> page = activitiService.affairPage(sql, params, pageable);
		return DataGrid.gridBuilder(page.getContent());
	}
	
	/**
	 * 获取流程定义的所有节点
	 * @param processDefinitionId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("process/processDefinitionTasks")
	public DataGrid processDefinitionTasks(String processKey,String processDefinitionId){
		BpmnModel model = activitiService.getRepositoryService().getBpmnModel(processDefinitionId);
		List<JSONObject> list = new ArrayList<>();
		if(model != null) {  
		    Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements();  
		    for(FlowElement e : flowElements) {  
		    	JSONObject item = new JSONObject();
		    	item.put("processKey", processKey);
		    	item.put("taskId", e.getId()); item.put("taskName", e.getName()); item.put("taskClass", e.getClass().toString());
		    	TaskCandidateUsers taskUser = activitiService.getTaskCandidateUsersRepository()
		    				.findByProcessKeyAndTaskId(processKey, e.getId());
		    	if(taskUser!=null){
		    		item.put("candidateUsers", taskUser.getCandidateUsers());
		    	}
		        list.add(item);
		    }  
		}  
		return DataGrid.gridBuilder(list);
	}
	
	/**
	 * 设置流程节点候选人
	 * @param request
	 * @param users
	 * @return
	 */
	@Transactional
	@ResponseBody
	@RequestMapping("process/setTaskCandidateUsers")
	public JsonResponse setTaskUsers(HttpServletRequest request,TaskCandidateUsers taskCandidateUsers ){
		try {
			activitiService.updateTaskCandidateUser(taskCandidateUsers);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
		return JsonResponse.success();
	}
	
	@GetMapping("comment/index")
	public String commentIndex(HttpServletRequest req,String processInstanceId) {
		req.setAttribute("processInstanceId", processInstanceId);
		return SysPath.BACK_PATH.concat("/activiti/comment/index");
	}
	
	@RequestMapping("comment/commentList")
	@ResponseBody
	public DataGrid VocommentList(HttpServletRequest req,String processInstanceId){
		List<CommentVo> rows = new ArrayList<>();
		List<Comment> comments=activitiService.getTaskService().getProcessInstanceComments(processInstanceId);
		for(Comment c: comments){
			CommentEntity cEntity = (CommentEntity) c;
			rows.add(new CommentVo(c.getTime(), c.getUserId(), cEntity.getMessage()));
		}
		return DataGrid.gridBuilder(rows);
	}
	
	@GetMapping("processInstanceDelete")
	@ResponseBody
	public JsonResponse processInstanceDelete(String id) {
		try {
			activitiService.deleteProcessInstance(id);
			//activitiService.getRuntimeService().deleteProcessInstance(id,"错误实例[id"+ id + "]");//删除流程
			//activitiService.getHistoryService().deleteHistoricProcessInstance(id);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
	@GetMapping("processDefinition/config")
	public String config(HttpServletRequest req,String processInstanceId) {
		req.setAttribute("processInstanceId", processInstanceId);
		return SysPath.BACK_PATH.concat("/activiti/deploy/config");
	}
	
	
	/** 
	* 根据流程的key生成图片 
	*  
	* @param request 
	* @param response 
	* @param wfKey 流程定义的key 
	*/  
	@RequestMapping("/genericImageByWfKey")  
	public void genericImageByWfKey(HttpServletRequest request, HttpServletResponse response, String wfKey) {  
	    //Context.setProcessEngineConfiguration(processEngineConfiguration);  
	    RepositoryService repositoryService = activitiService.getRepositoryService();
	    response.setCharacterEncoding("UTF-8");
	    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey(wfKey).latestVersion().singleResult();  
	    //BpmnModel bm = repositoryService.getBpmnModel(pd.getId());  
	    //InputStream is = new DefaultProcessDiagramGenerator().generatePngDiagram(bm); // 生成图片，获取图片的输入流</span></strong>
	    //InputStream is = new DefaultProcessDiagramGenerator().generatePngDiagram(bpmnModel, scaleFactor)
	    //List<String> activeIds = activitiService.getRuntimeService().getActiveActivityIds(pd.getId());
	    //System.out.println(activeIds);
	    /*InputStream is = new DefaultProcessDiagramGenerator().generateDiagram(
	    		bm, "png",
	    		Collections.<String>emptyList(), Collections.<String>emptyList(), 
			    "宋体", 
			    "宋体", 
			    null, 1.0);*/
	    try {  
	      /*  int size = is.available();  
	        byte data[] = new byte[size];  
	        is.read(data);  
	        response.setCharacterEncoding("UTF-8");
	        response.setContentType("image/png"); // 设置返回的文件类型  
	        OutputStream os = response.getOutputStream();  
	        os.write(data);  
	        os.flush();  
	        os.close();  */
	    } catch (Exception e) {  
	        log.error("读写流程图时出现异常！");  
	    }  
	}  
	
    /** 
     * 获取各个节点的具体的信息 
     * @param wfKey 
     *      流程定义的key 
     * @return 
     */  
	@RequestMapping("/getProcessTrace")  
    @ResponseBody
    public List<Map<String, Object>> getProcessTrace(String wfKey) throws Exception {  
        List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();  
        RepositoryService repositoryService = activitiService.getRepositoryService();
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey(wfKey).latestVersion().singleResult();  
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(pd.getId());  
        List<ActivityImpl> activitiList = processDefinition.getActivities();  
        for (ActivityImpl activity : activitiList) {  
            Map<String, Object> infor = new HashMap<String, Object>();  
            infor.put("width", activity.getWidth()+2);  
            infor.put("height", activity.getHeight()+2);  
            infor.put("x", activity.getX());  
            infor.put("y", activity.getY());  
            infor.put("actId", activity.getId());  
            if(activity.getProperties().containsKey("type")){
            	infor.put("type", activity.getProperties().get("type"));  
            }else{
            	infor.put("type", "none");  
            }
            infor.put("name", activity.getProperty("name")); //ActivityImpl 中没有getName方法，所以此处需要这样获取。</span>  
            activityInfos.add(infor);  
        }  
        return activityInfos;  
    }  
	
	/**
	 * 流程节点配置
	 * @param request
	 * @param task
	 * @return
	 */
	@Transactional
	@ResponseBody
	@RequestMapping("configTask")
	public JsonResponse configTask(HttpServletRequest request,ProcessTaskConfig task){
		try {
			String processKey = task.getProcessKey();
			String taskId = task.getTaskId();
			if("exclusiveGateway".equals(task.getTaskType())){
				Map<String, Object> data = ApplicationUtils.getRequestDatas();
				Object val = null; 
				for(String sequenceFlowId: data.keySet()){
					if(sequenceFlowId.startsWith("flow")){
						val = data.get(sequenceFlowId);
						FlowCondition condition = flowConditionRepository.findByProcessKeyAndTaskIdAndSequenceFlowId(processKey, taskId,sequenceFlowId);
						if(condition==null){
							condition = new FlowCondition();
							condition.setProcessKey(processKey);
							condition.setTaskId(taskId);
							condition.setSequenceFlowId(sequenceFlowId);
						}
						condition.setExpress(val.toString());
						flowConditionRepository.save(condition);
					}else{
						continue;
					}
				}
			}else{
				ProcessTaskConfig taskVo = processTaskConfigRepository.findByProcessKeyAndTaskId(processKey, taskId);
				if(taskVo==null){
					taskVo = task;
				}else{
					BeanUtils.copyProperties(task, taskVo, new String[]{"id","createTime","createrName","orgNo","orgName"});
				}
				processTaskConfigRepository.save(taskVo);
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
		return JsonResponse.success();
	}
	
	
	/**
	 * 获取当前节点的outgoingFlows
	 * @param key
	 * @param taskId
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/resource/outgoingFlows")
	public Object nextSequenceFlows(HttpServletRequest request){
		JSONArray array = new JSONArray();
	    try {
	    	String key = request.getParameter("key");
	    	String taskId = request.getParameter("taskId");
	    	if(StringUtils.isNotBlank(key)&& StringUtils.isNoneBlank(taskId)){
	    		BpmnModel model = activitiService.getBpmnModel(key);
	    		FlowElement node = model.getFlowElement(taskId);
	    		if(node instanceof ExclusiveGateway){
	    			ExclusiveGateway exGateway = (ExclusiveGateway) node;
	    			List<SequenceFlow> flows = exGateway.getOutgoingFlows();
	    			FlowCondition condition = null;
	    			String express = null;
	    			for(SequenceFlow f: flows){
	    				JSONObject item = new JSONObject();
	    				item.put("name", f.getName());
	    				item.put("id", f.getId());
	    				express = f.getConditionExpression();
	    				condition = flowConditionRepository.findByProcessKeyAndTaskIdAndSequenceFlowId(key, taskId, f.getId());
	    				if(condition!=null){
	    					if(StringUtils.isNotBlank(express)){
	    						express = express.concat("&&").concat(condition.getExpress());
	    					}else{
	    						express = condition.getExpress();
	    					}
	    				}
	    				item.put("conditionExpression",express);
	    				array.add(item);
	    			}
	    		}
	    	}
		} catch (Exception e) {
			e.printStackTrace();
		}
	    return array;
	}
	
	/**
	 * 流程跳转到处理表单
	 * @param modleName
	 * @param req
	 * @return
	 */
	@GetMapping("{modleName}/processForm")
	public String preAdd(@PathVariable String modleName, HttpServletRequest req) {
		req.setAttribute("modleName", modleName);
		req.setAttribute("className", SysConstant.MODLE_CLASSNAME.get(modleName));
		String taskId = req.getParameter("taskId");
		if(StringUtils.isNotBlank(taskId)){
			Task task = activitiService.findTaskById(taskId);
		}
		return SysPath.BACK_PATH.concat("/"+modleName).concat("/processForm");
	}
	
	
	@Transactional
	@ResponseBody
	@RequestMapping(value = "startOrSubmit")
	public JsonResponse startOrSubmit(HttpServletRequest request){
		try {
			boolean isSuccess = false;
			String taskId = request.getParameter("taskId");
			String processKey = request.getParameter("className");
			String businessKey = processKey;
			if(StringUtils.isBlank(taskId)){//启动
				Map<String, Object> map = ApplicationUtils.getRequestDatas();
				Object vo = Class.forName(processKey).newInstance();
				String json = JSON.toJSONString(map);
				vo = JSON.parseObject(json, vo.getClass());
				vo = baseService.beanRepository(processKey).save(vo);
				
				switch (processKey) {
					case "com.fs.jzzn.pojo.NoteDebit":
						NoteDebit debit = (NoteDebit) vo;
						businessKey = processKey + "#" + debit.getId();
						break;
					default:
						break;
					}
				
				RuntimeService runtimeService = activitiService.getRuntimeService();
				TaskService taskService = activitiService.getTaskService();
				
				/*
				 * 认证
				 */
				Authentication.setAuthenticatedUserId(ApplicationUtils.User().getNickName());
				ProcessInstance pi = runtimeService.startProcessInstanceByKey(processKey, businessKey);
				
				runtimeService.setProcessInstanceName(pi.getId(),"发起流程");
				
				Task task = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).singleResult(); // 根据流程实例Id查询任务
				// 完成用户申请任务
				taskService.setAssignee(task.getId(), ApplicationUtils.User().getNickName());
				
				Execution execu = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
				String activityId = execu.getActivityId();
				Map<String, Object> variables = new HashMap<String, Object>();
				ProcessTaskConfig config = processTaskConfigRepository.findByProcessKeyAndTaskId(processKey, activityId);
				if(config!=null){
					String vars = config.getVariableField();
					for(String key : vars.split("#")){
						if(map.containsKey(key)){
							variables.put(key, map.get(key));
						}
					}
				}
				taskService.complete(task.getId(),variables);  
				isSuccess = true;
				
			}else{//节点处理提交
				
			}
			if(isSuccess){
				return JsonResponse.success();
			}else{
				return JsonResponse.error("处理流程失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
}
